package com.mall.order.mq.delay;

import com.mall.order.dal.entitys.Order;
import com.mall.order.dal.entitys.OrderItem;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.OrderItemMapper;
import com.mall.order.dal.persistence.OrderMapper;
import com.mall.order.dal.persistence.StockMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

/**
 * 创建日期: 2022/01/24 22:09
 *
 * @author ghr
 */
@Slf4j
@Component
public class DelayOrderCancelConsumer {
    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    StockMapper stockMapper;

    private DefaultMQPushConsumer consumer;

    @PostConstruct
    public void init() {
        // 创建用于消费信息的consumer对象
        consumer = new DefaultMQPushConsumer("delay_order_cancel_consumer");

        // 设置nameserver地址
        consumer.setNamesrvAddr("127.0.0.1:9876");

        // 设置消息监听器
        consumer.setMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                // 获取消息
                MessageExt message = list.get(0);

                // 获取orderId
                byte[] body = message.getBody();
                String orderId = null;
                try {
                    orderId = new String(body, 0, body.length, "utf-8");
                    System.out.println("接收到消息 " + message.getMsgId() + ":" + orderId);
                } catch (UnsupportedEncodingException e) {
                    log.info("接收消息时发生了异常");
                    e.printStackTrace();
                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                }
                // 根据orderId去数据库中，检查orderId对应的订单,有没有支付
                //  a.如果订单已经支付成功，或者订单已经被取消，啥也不干
                //  b.如果订单处于初始化状态，指定时间内，没有支付成功，执行订单的取消
                Order order = orderMapper.selectByPrimaryKey(orderId);
                Integer status = order.getStatus();
                // 如果执行订单的自动取消:
                //  a.修改订单状态为已取消
                //  b.遍历订单中的每一个订单商品条目，根据每个商品的下单数量-lockCount +stockCount
                if (status == 0) {
                    order.setStatus(7);
                    order.setCloseTime(new Date());
                    orderMapper.updateByPrimaryKeySelective(order);
                    orderItemMapper.updateStockStatus(2, orderId);
                    Example example = new Example(OrderItem.class);
                    example.createCriteria().andEqualTo("orderId", orderId);
                    List<OrderItem> orderItems = orderItemMapper.selectByExample(example);
                    for (OrderItem orderItem : orderItems) {
                        Long itemId = orderItem.getItemId();
                        Integer num = orderItem.getNum();
                        Stock stock = new Stock();
                        stock.setItemId(itemId);
                        stock.setLockCount(-num);
                        stock.setStockCount(Long.parseLong(num + ""));
                        stockMapper.updateStock(stock);
                    }
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });

        // 订阅主题
        try {
            consumer.subscribe("delay_order_cancel", "*");

            consumer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }
}